package com.mmall.service.impl;


import com.mmall.common.Const;
import com.mmall.common.ServerResponse;
import com.mmall.common.TokenCache;
import com.mmall.dao.UserMapper;
import com.mmall.pojo.User;
import com.mmall.service.IUserService;
import com.mmall.util.MD5Util;
import org.apache.commons.lang3.StringUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.util.UUID;

/**
 * Created by Administrator on 2017/5/23 0023.
 */
@Service("iUserService")
//把service注入到Controller上,供Controller调用
public class UserServiceImpl implements IUserService {

    @Autowired
    private UserMapper userMapper;


    /*
    登录
       业务逻辑：
     */
    @Override
    public ServerResponse<User> login(String username, String password) {
        int resultCount = userMapper.checkUsername(username);
        if (resultCount == 0) {
            return ServerResponse.createByErrorMessage("用户名不存在");
        }

        //登陆密码MD5加密
        String md5password = MD5Util.MD5EncodeUtf8(password);

        User user = userMapper.selectLogin(username, md5password);
        if (user == null) {
            return ServerResponse.createByErrorMessage("密码错误！");
        }
        //TODO  使用工具而不用设置为空值，不直接设置为“” 为什么？
        /*
        为了安全考虑，把密码设置为空值
         */
        user.setPassword(StringUtils.EMPTY);
        return ServerResponse.createBySuccessMessageAndData("登录成功", user);


    }

    //注册
    public ServerResponse<String> register(User user) {

        ServerResponse ValidResponse = this.checkValid(user.getUsername(), Const.USERNAME);
        if (!ValidResponse.isSuccess()) {
            return ValidResponse;
        }

        ValidResponse = this.checkValid(user.getEmail(), Const.EMAIL);
        if (!ValidResponse.isSuccess()) {
            return ValidResponse;
        }


        user.setRole(Const.Role.ROLE_CUSTOMER);
        //MD5加密
        user.setPassword(MD5Util.MD5EncodeUtf8(user.getPassword()));

        int resultCount = userMapper.insert(user);
        if (resultCount == 0) {
            return ServerResponse.createByErrorMessage("注册失败");
        }

        return ServerResponse.createByErrorMessage("注册成功");
    }


    /**
     * 防止恶意用户通过接口调用注册接口
     * 通过向数据库查询，验证该用户是否存在
     */
    public ServerResponse<String> checkValid(String str, String type) {
        //判断type是否为空或者" 空格 "
        if (StringUtils.isNotBlank(type)) {
            //开始校验

            //1.验证用户名
            if (Const.USERNAME.equals(type)) {
                int resultCount = userMapper.checkUsername(str);
                if (resultCount > 0) {
                    return ServerResponse.createByErrorMessage("用户名已存在");
                }
            }
            //1.验证用邮箱
            if (Const.EMAIL.equals(type)) {
                System.out.println(Const.EMAIL);
                int resultCount = userMapper.checkEmail(str);
                if (resultCount > 0) {
                    return ServerResponse.createByErrorMessage("邮箱已存在");
                }
            }
        } else {
            return ServerResponse.createByErrorMessage("参数错误");
        }
        return ServerResponse.createBySuccessMessage("验证成功");
    }


    public ServerResponse selectQuestion(String username) {
        ServerResponse ValidResponse = this.checkValid(username, Const.USERNAME);
        if (ValidResponse.isSuccess()) {

            return ServerResponse.createByErrorMessage("用户不存在");
        }
        String qusetion = userMapper.selectQuestionByUsername(username);
        if (StringUtils.isNotBlank(qusetion)) {
            return ServerResponse.createBySuccessData(qusetion);
        }
        return ServerResponse.createByErrorMessage("找回密码的问题是空的");
    }

    public ServerResponse<String> checkAnswer(String username, String question, String answer) {
        int resultCount = userMapper.checkAnswer(username, question, answer);
        if (resultCount > 0) {
            //说明问题及问题答案是这个用户的，并且答案正确
            String forgetToken = UUID.randomUUID().toString();
            TokenCache.setKey(TokenCache.TOKEN_PREFIX + username, forgetToken);
            return ServerResponse.createBySuccessMessage(forgetToken);
        }
        return ServerResponse.createByErrorMessage("问题的答案错误");

    }

    /**
     * 接口：忘记密码
     *
     * author:张小旭
     *
     * @param username
     * @param passwordNew
     * @param forgetToken
     * @return
     */
    public ServerResponse<String> forgetResetPassword(String username, String passwordNew, String forgetToken) {
        if (StringUtils.isBlank(forgetToken)) {
            return ServerResponse.createByErrorMessage("参数错误，token需要传递");
        }
        //验证用户是否存在
        //todo:如果是空值会不会存在bug?
        ServerResponse ValidResponse = this.checkValid(username, Const.USERNAME);
        if (ValidResponse.isSuccess()) {
            //用户不存在
            return ServerResponse.createByErrorMessage("用户不存在");
        }
        String token = TokenCache.getValueByKey(TokenCache.TOKEN_PREFIX + username);
        if (StringUtils.isBlank(token)) {
            ServerResponse.createByErrorMessage("token无效或者过期");
        }

        //不使用a.equals(b),是为了避免如果a为null产生的空指针异常
        if (StringUtils.equals(forgetToken, token)) {
            String md5password = MD5Util.MD5EncodeUtf8(passwordNew);
            int rowCount = userMapper.updatePasswordByUsername(username, md5password);
            if (rowCount > 0) {
                return ServerResponse.createBySuccessMessage("修改密码成功");
            }
        } else {
            return ServerResponse.createByErrorMessage("token错误，请重新获取重置密码的token");
        }
        return ServerResponse.createByErrorMessage("修改密码失败");

    }

    public ServerResponse<String> resetPassword(String passwordOld, String passwordNew, User user) {
        //传入 是为了防止横向越权（要校验一下用户的旧密码，一定是该登陆用户的。
        // 因为我们会查询一个count（1），如果不指定id,那结果就是true了count>0）

        int resultCount = userMapper.checkPassword(MD5Util.MD5EncodeUtf8(passwordOld), user.getId());
        if (resultCount == 0) {
            return ServerResponse.createByErrorMessage("旧密码错误");
        }
        user.setPassword(MD5Util.MD5EncodeUtf8(passwordNew));
        resultCount = userMapper.updateByPrimaryKeySelective(user);
        if (resultCount > 0) {
            return ServerResponse.createBySuccessMessage("密码更新成功");
        }
        return ServerResponse.createByErrorMessage("密码更新失败");
    }

    public ServerResponse<User> updateInformation(User user) {
        //用户的username是不能被更新的
        //校验邮箱，校验新的邮箱是否已经存在。如果已存在，不能是当前 这个用户的
        int resultCount = userMapper.checkEmailByUserId(user.getEmail(), user.getId());
        if (resultCount > 0) {
            return ServerResponse.createByErrorMessage("email已存在，请更换email再尝试更新");
        }
        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setPhone(user.getPhone());
        updateUser.setQuestion(user.getQuestion());
        updateUser.setAnswer(user.getAnswer());
        updateUser.setEmail(user.getEmail());
        updateUser.setUsername(user.getUsername());

        int updateCount = userMapper.updateByPrimaryKeySelective(updateUser);
        if (updateCount == 0) {
            return ServerResponse.createByErrorMessage("更新个人信息失败");
        }
        return ServerResponse.createBySuccessMessageAndData("更新个人信息成功", updateUser);
    }

    public ServerResponse<User> getInformation(Integer userId) {
        User user = userMapper.selectByPrimaryKey(userId);
        if (user == null) {
            return ServerResponse.createByErrorMessage("找不到当前用户");
        }
        user.setPassword(StringUtils.EMPTY);
        return ServerResponse.createBySuccessData(user);
    }

    //backend


    /**
     * 校验是否是管理员
     *
     * @param user
     * @return
     */
    public ServerResponse checkAdminRole(User user) {
        //********************************以int类型返回该Integer的值
        if (user != null && user.getRole().intValue() == Const.Role.ROLE_ADMIN) {
            return ServerResponse.createBySuccess();
        }
        return ServerResponse.createByError();
    }


}
